<template>
	<div style="position: relative;">
		<el-table ref="dataTable" :max-height="maxHeight" :data="dataList" :width="mTableProps.width"
			:stripe="mTableProps.stripe" :border="mTableProps.border" :size="mTableProps.size"
			:show-header="mTableProps.showHeader" :highlight-current-row="mTableProps.highlightCurrentRow"
			:highlight-selection-row="mTableProps.highlightSelectionRow" :current-row-key="mTableProps.currentRowKey"
			:row-class-name="mTableProps.rowClassName" :row-style="mTableProps.rowStyle"
			:cell-class-name="mTableProps.cellClassName" :cell-style="mTableProps.cellStyle"
			:header-row-class-name="mTableProps.headerRowClassName" :header-row-style="mTableProps.headerRowStyle"
			:header-cell-class-name="mTableProps.headerCellClassName" :header-cell-style="mTableProps.headerCellStyle"
			:row-key="mTableProps.rowKey" :empty-text="mTableProps.emptyText"
			:default-expand-all="mTableProps.defaultExpandAll" :expand-row-keys="mTableProps.expandRowKeys"
			:tooltip-effect="mTableProps.tooltipEffect" :show-summary="mTableProps.showSummary"
			:sum-text="mTableProps.sumText" :summary-method="mTableProps.summaryMethod"
			:span-method="mTableProps.spanMethod" :select-on-indeterminate="mTableProps.selectOnIndeterminate"
			:indent="mTableProps.indent" :lazy="mTableProps.lazy" :load="mTableProps.load"
			:tree-props="mTableProps.treeProps" @select="tableSelect" @select-all="tableSelectAll"
			@selection-change="tableSelectionChange" @cell-mouse-enter="tableCellMouseEnter"
			@cell-mouse-leave="tableCellMouseLeave" @cell-click="tableCellClick" @cell-dblclick="tableCellDblclick"
			@row-click="tableRowClick" @row-contextmenu="tableRowContextmenu" @row-dblclick="tableRowDblclick"
			@header-click="tableHeaderClick" @header-contextmenu="tableHeaderContextmenu"
			@current-change="tableCurrentChange" @header-dragend="tableHeaderDragend"
			@expand-change="tableExpandChange">
			<slot :name="item.prop" v-for="(item, index) in columnList" v-if="item.isShow">
				<el-table-column :type="item.type" :index="index" :key="index" :label="item.label" :prop="item.prop"
					:fixed="item.fixed" :render-header="item.renderHeader" :formatter="item.formatter"
					:width="item.width" :show-overflow-tooltip="item.showOverflowTooltip"
					:align="item.align?item.align:'center'" :header-align="item.headerAlign"
					:class-name="item.className" :label-class-name="item.labelClassName" :selectable="item.selectable"
					:reserve-selection="item.reserveSelection">
					<template slot="header" slot-scope="scope">
						<div class="flex align-center justify-center">
							{{item.label}}
							<div class="flex align-center">
								<div v-if="item.isSort" class="flex flex-direction align-center" style="line-height:0;">
									<div class="" @click="sortChange(item,item.prop,'asc')" style="cursor: pointer;">
										<i class="el-icon-caret-top" style="color:#409EFF"
											v-if="item.sortIsAsc === true"></i>
										<i class="el-icon-caret-top" v-else style="color:#C0C4CC"></i>
									</div>
									<div class="" style="margin-top:-6px;cursor: pointer;"
										@click="sortChange(item,item.prop,'desc')">
										<i class="el-icon-caret-bottom" style="color:#409EFF"
											v-if="item.sortIsAsc === false"></i>
										<i class="el-icon-caret-bottom" style="color:#C0C4CC" v-else></i>
									</div>
								</div>

								<el-popover v-if="item.isFilter" placement="bottom" width="60" height="300"
									trigger="click" popper-class="headerFilter">
									<div class="" style="overflow-y:auto;max-height:200px;">
										<el-checkbox :indeterminate="item.filterIsIndeterminate"
											v-model="item.filterIsAll"
											@change="handleCheckAllChange($event,item)">全选</el-checkbox>
										<el-checkbox-group v-model="item.filteredValue"
											@change="handleCheckedShaixuanChange($event,item)">
											<div style="display:flex;flex-direction: column;margin-top:10px;">
												<el-checkbox v-for="mItem in item.options()" :label="mItem.value"
													:key="mItem.value">{{mItem.label}}</el-checkbox>
											</div>
										</el-checkbox-group>
									</div>

									<el-button slot="reference" style="padding:0;border:none;background:transparent;">
										<img v-if="item.filteredValue.length <= 0" src="./icon/filter-0.png"
											style="width: 16px;height:16px;margin-top:8px;" />
										<img v-else src="./icon/filter-1.png"
											style="width: 16px;height:16px;margin-top:8px;" />
									</el-button>
								</el-popover>
							</div>
						</div>
					</template>
					<!-- 头像 -->
					<template v-if="item.type == 'avatar'" v-slot="scope">
						<el-avatar v-if="scope.row[item.prop]" :src="scope.row[item.prop]" :fit="item.fit"
							:shape="item.shape" :srcSet="item.srcSet" :style="item.style"></el-avatar>
					</template>
					<!-- 图片 -->
					<template v-else-if="item.type == 'file'" v-slot="scope">
						<div v-if="getPicturesValue(scope.row[item.prop]).length>0"
							class="flex align-center justify-center">
							<el-image v-if="getPicturesValue(scope.row[item.prop]).length <= 1"
								:src="scope.row[item.prop]" :preview-src-list="[scope.row[item.prop]]"
								:fit="item.fit?item.fit:'fill'" :style="item.style"></el-image>

							<div v-else class="flex align-center">
								<el-image :src="getPicturesValue(scope.row[item.prop])[0]"
									:preview-src-list="getPicturesValue(scope.row[item.prop])"
									:fit="item.fit?item.fit:'fill'" :style="item.style" class="mr3"></el-image>
								<template v-if="getPicturesValue(scope.row[item.prop]).length > 1">
									共{{getPicturesValue(scope.row[item.prop]).length}}张
								</template>
							</div>
						</div>
					</template>
					<!-- icon -->
					<template v-else-if="item.type == 'icon'" v-slot="scope">
						<div v-if="scope.row[item.prop] != null && scope.row[item.prop] != ''">
							<i :class="scope.row[item.prop]" style="font-size:20px" :style="item.style"></i>
						</div>
					</template>
					<!-- 长文本 -->
					<template v-else-if="item.type == 'longText'" v-slot="scope">
						<el-popover placement="top-start" width="200" trigger="hover" :content="scope.row[item.prop]"
							:style="item.style">
							<div class="ellipsis" slot="reference">
								{{ scope.row[item.prop] }}
							</div>
						</el-popover>
					</template>

					<!-- switch开关 -->
					<template v-else-if="item.type == 'switch'" v-slot="scope">
						<el-switch v-model="scope.row[item.prop]" :active-value="item.active"
							:inactive-value="item.inactive"
							@change="statusChangeMethod(scope.row, item.prop, item.active, item.inactive)"
							:style="item.style">
						</el-switch>
					</template>

					<!-- json -->
					<template v-else-if="item.type == 'json'" v-slot="scope">
						<el-popover placement="top-start" width="370" trigger="hover" :style="item.style">
							<json-viewer :value="scope.row[item.prop]" :expand-depth="4" copyable sort></json-viewer>
							<div class="ellipsis" slot="reference">
								{{ scope.row[item.prop] }}
							</div>
						</el-popover>
					</template>
					<!-- tag -->
					<template v-else-if="item.type == 'tag'" v-slot="scope">
						<span v-for="(optionItem, optionIndex) in colTagGetOptions(item.options)" :key="optionIndex">
							<el-tag v-if="colTagGetValue(scope.row[item.prop]).includes(optionItem.value + '')"
								:type="optionItem.type" :style="item.style">
								{{ optionItem.label }}
							</el-tag>
						</span>
					</template>
					<!-- 预览 -->
					<template v-else-if="item.type == 'fuwenben'" v-slot="scope">
						<el-button v-if="$common.isNotBlank(scope.row[item.prop])" type="primary" plain size="mini"
							@click="yulanShowClick(scope.row[item.prop])" :style="item.style">查看</el-button>
					</template>
					<!-- 复制 -->
					<template v-else-if="item.type == 'copy'" v-slot="scope">


						<div v-clipboard:copy="scope.row[item.prop]" v-clipboard:success="copySuccess"
							:style="item.style" class="ellipsis">
							<el-link type="primary">{{scope.row[item.prop]}}</el-link>
						</div>
					</template>
					<!-- 链接 -->
					<template v-else-if="item.type == 'link'" v-slot="scope">
						<el-link :icon="item.icon" :underline="item.underline" :type="item.linkType"
							:href="scope.row[item.prop]" target="_blank">{{scope.row[item.prop]}}</el-link>
					</template>
					<template v-else v-slot="scope">
						<span :style="item.style">{{scope.row[item.prop]}}</span>
					</template>
				</el-table-column>
			</slot>
			<slot></slot>
		</el-table>
		<!-- 分页 -->
		<el-pagination id="page" v-if="isPage" @size-change="handleSizeChange" @current-change="handleCurrentChange"
			:current-page="pageData.current" :page-sizes="[10,20,30,50]" :page-size="pageData.size"
			layout="total, sizes, prev, pager, next, jumper" :total="pageData.total" background>
		</el-pagination>
		<gz-yulan ref="gzYulanRef"></gz-yulan>
	</div>
</template>
<script>
	import JsonViewer from 'vue-json-viewer'
	import lodash from 'lodash';
	
	export default {
		name: "gz-table",
		components: {
			JsonViewer
		},
		created() {},
		props: {
			name: {
				default: ""
			},
			searchData: {
				type: Object,
				default: {}
			},
			//查询事件
			api: {
				type: String,
				required: true,
				default: null,
			},
			//表格参数配置
			columns: {
				type: Array,
				default () {
					return []
				},
			},
			isColSet: {
				type: Boolean,
				default: false
			},
			isPage: {
				type: Boolean,
				default: true,
			},
			tableProps: {
				default: () => {
					return {
						stripe: false,
						showHeader: true,
						rowStyle: {
							height: '45px',
						},
						cellStyle: {
							padding: '0 ',
							'text-align': 'center',
						},
						headerCellStyle: {
							'text-align': 'center',
							color: '#606266',
							'background-color': '#F8F8F9',
							padding: '0px 0'
						},
						width: "100%",
						rowKey: "id",
						highlightCurrentRow: false,
						headerRowStyle: {

						}
					}
				}
			},
			showSearch:true
		},
		watch: {
			tableProps: {
				handler(newValue, oldValue) {
					let defaultValue = {
						stripe: false,
						showHeader: true,
						rowStyle: {
							height: '45px',
						},
						cellStyle: {
							padding: '0 ',
							'text-align': 'center',
						},
						headerCellStyle: {
							'text-align': 'center',
							color: '#606266',
							'background-color': '#F8F8F9',
							padding: '0px 0'
						},
						width: "100%",
						rowKey: "id",
						highlightCurrentRow: false,
						headerRowStyle: {

						}
					}
					let mTableProps = this.tableProps ? this.tableProps : {}
					Object.assign(defaultValue, mTableProps)
					this.mTableProps = defaultValue
				},
				deep: true,
				immediate: true,
			},
			showSearch: {
				handler(newValue, oldValue) {
					this.refreshSize()
				},
				deep: true,
				immediate: true,
			}
		},
		data() {
			return {
				tableName: "",
				pageData: {
					current: 1,
					size: 10,
					total: 0,
					orders: []
				},
				dataList: [],
				maxHeight: null,
				params: {},
				columnList: [],
				mTableProps: {}
			};
		},
		mounted() {
			if (this.name) {
				this.tableName = this.name + "-TABLE"
			} else {
				this.tableName = this.$route.name + "-TABLE"
			}
			//初始化列
			this.columnInit()

			this.$nextTick(()=>{
				window.onresize = () => {
					return (() => {
						this.refreshSize()
					})()
				}
				setTimeout(()=>{
					this.refreshSize()
				},500)
			})
		},
		methods: {
			handleCheckAllChange(val, item) {
				item.filterIsAll = val
				item.filteredValue = val ? item.options().map(item => item.value) : [];
				item.filterIsIndeterminate = false;
				this.pageData[item.prop] = item.filteredValue
				this.shuaxin()
			},
			handleCheckedShaixuanChange(value, item) {
				console.info("handleCheckedShaixuanChange", value)
				let checkedCount = value.length;
				item.filterIsAll = checkedCount === item.options().length;
				item.filterIsIndeterminate = checkedCount > 0 && checkedCount < item.options().length;

				this.pageData[item.prop] = item.filteredValue
				this.shuaxin()
			},
			shuaxin(params) {
				if (params) {
					this.params = params
					this.searchData = params
				}
				this.pageData.current = 1
				this.findAllByPage()
			},
			refreshSize() {
				console.info("document.body.clientHeight", document.body.clientHeight)
				let formEl = document.getElementById("searchForm")
				let clientHeight = 0
				if(formEl){
					clientHeight = formEl.clientHeight
				}
				let operateEl = document.getElementById("operate")
				let operateHeight = 0
				if(operateEl){
					operateHeight = operateEl.clientHeight
				}
				let pageEl = document.getElementById("page")
				let pageHeight = 0
				if(pageEl){
					pageHeight = pageEl.clientHeight
				}
				//暂时支持刷新高度
				this.maxHeight = document.body.clientHeight - 50 - 20 - operateHeight - clientHeight - pageHeight - 10
			},
			sortChange(item, prop, sort) {
				let sortIsAsc = null
				if (item.sortIsAsc == null) {
					sortIsAsc = sort == "asc" ? true : false
				} else if (item.sortIsAsc == true) {
					if (sort == "asc") {
						sortIsAsc = null
					} else {
						sortIsAsc = false
					}
				} else {
					if (sort == "desc") {
						sortIsAsc = null
					} else {
						sortIsAsc = true
					}
				}
				item.sortIsAsc = sortIsAsc
				if (sortIsAsc == null) {
					let index = this.pageData.orders.findIndex(item => item.column == prop)
					if (index != -1) {
						this.pageData.orders.splice(index, 1)
					}
				} else {
					let orderItem = {
						column: prop,
						asc: sort == 'asc' ? true : false
					}
					let index = this.pageData.orders.findIndex(item => item.column == prop)
					if (index == -1) {
						this.pageData.orders.push(orderItem)
					} else {
						this.pageData.orders[index] = orderItem
					}
				}

				this.shuaxin()
			},
			findAllByPage() {
				if (this.$common.isBlank(this.api)) {
					return
				}
				let searchData = JSON.parse(JSON.stringify(this.searchData))

				Object.assign(searchData, this.pageData);

				searchData.orders = this.pageData.orders.map(item => item.column + ":" + item.asc).join(",")

				for (let key in searchData) {
					if (Array.isArray(searchData[key])) {
						searchData[key] = searchData[key].join(",")
					}
				}
				this.$api[this.api](searchData).then((result) => {
					if (this.isPage) {
						this.dataList = result.records
						this.pageData.total = result.total
					} else {
						this.dataList = result
					}
				})
			},
			clearFilter() {
				this.columnList.forEach(item => {
					if (item.isFilter) {
						item.filterIsAll = []
						item.filteredValue = []
						item.filterIsIndeterminate = false;
						this.pageData[item.prop] = item.filteredValue
					}
					if (item.isSort) {
						item.sortIsAsc = null
					}
				})
				this.pageData.orders = []

			},
			//框选中
			handleSelectionChange(val) {
				this.$emit("handleSelectionChange", val);
			},
			//页条改变
			handleSizeChange(val) {
				this.pageData.size = val;
				//调用接口
				this.shuaxin();
			},
			//页码改变
			handleCurrentChange(val) {
				this.pageData.current = val;
				//调用接口
				this.findAllByPage();
			},
			//表格内状态改变
			statusChangeMethod(val, prop, active, inactive) {
				this.$confirm("确定更改状态?", "提示", {
						confirmButtonText: "确定",
						cancelButtonText: "取消",
						type: "warning",
					})
					.then(async () => {
						await this.$emit("handleSwitchChange", val, prop);
					})
					.catch(() => {
						val[prop] == active ? (val[prop] = inactive) : (val[prop] = active);
					});
			},
			yulanShowClick(content) {
				this.$refs.gzYulanRef.open({
					title: "预览内容",
					content: content
				})
			},
			getPicturesValue(img) {
				if (!img) {
					return []
				}
				if (Array.isArray(img)) {
					return img
				} else {
					if (img.indexOf(",") == -1) {
						return [img]
					} else {
						return img.split(",")
					}
				}
			},
			copySuccess() {
				this.$common.msgSuccess("已复制")
			},
			columnInit() {
				let columns = lodash.cloneDeep(this.columns)
				columns.forEach(item => {
					if (item.type == 'selection') {
						item.isShow = true
					} else {
						item.isShow = item.hasOwnProperty("isShow") ? item.isShow : true
						item.isSort = item.hasOwnProperty("isSort") ? item.isSort : false
						item.sortIsAsc = null
						item.isFilter = item.hasOwnProperty("isFilter") ? item.isFilter : false
						item.filteredValue = []
						item.options = item.hasOwnProperty("options") ? item.options : () => []
						item.filterIsAll = false
						item.filterIsIndeterminate = false
					}
				})
				
				if (this.isColSet) {
					let value = localStorage.getItem(this.tableName)
					if (value) {
						value = JSON.parse(value)
						columns.forEach(item => {
							if (item.type != 'selection') {
								let index = value.findIndex(mItem => mItem.prop == item.prop)
								if (index != -1) {
									item.isShow = value[index].hasOwnProperty("isShow") ? value[index].isShow :
										false
								} else {
									item.isShow = false
								}
							}
						})
					} else {
						let value = columns.filter(item => item.type != 'selection').map(item => {
							return {
								prop: item.prop,
								isShow: item.isShow
							}
						})
						localStorage.setItem(this.tableName, JSON.stringify(value))
					}
				}
				this.columnList = columns
			},
			// 表格事件
			tableSelect(selection, row) {
				this.$emit("select", selection, row)
			},
			tableSelectAll(selection) {
				this.$emit("select-all", selection)
			},
			tableSelectionChange(selection) {
				this.$emit("selection-change", selection)
			},
			tableCellMouseEnter(row, column, cell, event) {
				this.$emit("cell-mouse-enter", row, column, cell, event)
			},
			tableCellMouseLeave(row, column, cell, event) {
				this.$emit("cell-mouse-leave", row, column, cell, event)
			},
			tableCellClick(row, column, cell, event) {
				this.$emit("cell-click", row, column, cell, event)
			},
			tableCellDblclick(row, column, cell, event) {
				this.$emit("cell-dblclick", row, column, cell, event)
			},
			tableRowClick(row, column, event) {
				this.$emit("row-click", row, column, event)
			},
			tableRowContextmenu(row, column, event) {
				this.$emit("row-contextmenu", row, column, event)
			},
			tableRowDblclick(row, column, event) {
				this.$emit("row-dblclick", row, column, event)
			},
			tableHeaderClick(column, event) {
				this.$emit("header-click", column, event)
			},
			tableHeaderContextmenu(column, event) {
				this.$emit("header-contextmenu", column, event)
			},
			tableCurrentChange(currentRow, oldCurrentRow) {
				this.$emit("current-change", currentRow, oldCurrentRow)
			},
			tableHeaderDragend(newWidth, oldWidth, column, event) {
				this.$emit("header-dragend", newWidth, oldWidth, column, event)
			},
			tableExpandChange(row, expandedRowsOrExpanded) {
				this.$emit("expand-change", row, expandedRowsOrExpanded)
			},
			colTagGetOptions(options) {
				if (!options) {
					return []
				}
				if (Array.isArray(options)) {
					return options
				} else if (Object.prototype.toString.call(options) == '[object Function]') {
					let mOptions = options()
					mOptions.forEach(item => {
						if (item.raw) {
							item.type = item.raw.listClass
						}
					})
					return mOptions
				} else {
					return []
				}
			},
			colTagGetValue(value) {
				if (!value && value != '0') {
					return []
				}
				if (Array.isArray(value)) {
					return value
				} else {
					value = value + ""
					if (value.indexOf(",") == -1) {
						return [value]
					} else {
						return value.split(",")
					}
				}
			}
		},
	};
</script>

<style lang="scss">
	.headerFilter {
		min-width: 100px !important;
	}

	/deep/ .el-table__body-wrapper::-webkit-scrollbar {
		/*滚动条整体样式*/
		width: 6px;
		/*高宽分别对应横竖滚动条的尺寸*/
		height: 8px;
	}

	/deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
		/*滚动条里面小方块*/
		border-radius: 2px;
		background: #666;
	}

	/deep/ .el-table__body-wrapper::-webkit-scrollbar-track {
		/*滚动条里面轨道*/
		background: #ccc;
	}

	/deep/ .el-table__fixed-right::before,
	.el-table__fixed::before {
		background-color: unset;
	}

	.el-pagination {
		margin-top: 5px
	}
</style>